home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-03-19 | 83.2 KB | 2,333 lines | [TEXT/MPS ] |
- #/****************** This is a full line in MPW printing on an 8.5 x 11, in Courier 9 *******************/
- #########################################################################
- #########################################################################
- ## Copyright © Apple Computer, Inc. 1992-1997
- ## All rights reserved
- #########################################################################
- #########################################################################
- #
- # Library: Launchquits.lib
- #
- # Version: 2.1.4
- # Description:
- # This is a library for LaunchQuits. The launch and quit are separated into two
- # sequences, each with two endpoints and any number of items in between. The
- # sequences comprise milestones, or items to wait for designated by the term
- # 'awaitDesc', alternating with items to do, designated by the term 'doItem'.
- #
- # A sequence may contain conditional sub-sequences. If an awaitDesc is a list
- # instead of a descriptor, then the first item in this list is evaluated. If it
- # is true (i.e present for an awaitDesc or true for a conditional), the rest of
- # the list executed; if not, the whole list is ignored, and the engine continues
- # with the next item in the main list as an awaitDesc. The conditional
- # sub-sequence is used where a sequence branches into several paths
- # which converge later. The conditional returns true if all items pass or if
- # it is ignored because the first item failed, and returns false ONLY if the
- # first item passes and a subsequent item fails.
- #
- # CAUTION: In order to properly handle default sequences, a conditional
- # sub-sequence counts as an awaitDesc, even if it contains doItems. The item
- # following a conditional is always a doItem and is always selected unless the
- # conditional fails, i.e. it is selected even if conditional was ignored. You
- # can put an empty string as the doItem after a conditional so it does nothing.
- #
- # The CheckLaunchQuit task is the LQ Engine. It receives a list of test
- # definitions and other parameters from its caller, usually the LaunchQuit
- # Script. For each test definition, CheckLaunchQuit calls LaunchApplication,
- # then AppSequence, then LQCustom, then QuitSequence.
- #
- # The LaunchApplication task takes the CPU from where it is now to the
- # application running in the foreground. If the app is launched in the
- # background, it is then moved to the foreground. Note: If the application
- # is already running in the foreground, launching by AgentVUBG will not
- # move it to the background.
- #
- # The AppSequence task executes a sequence against a previously launched
- # application that is in the foreground, verifying each milestone on the
- # way. The default endpoint is [window t:/≈Untitled≈/ o:1], which is added
- # automatically if the last item in the sequence is a doItem.
- #
- # The LQCustom task is optional. It is the same for every app. After the
- # AppSequence task completes without errors, CheckLaunchQuit calls LQCustom.
- # The LQCustom.lib file contains this task, and it may do anything, as long
- # as the app is still running in the foreground when it completes. The
- # LQCustom task returns true in that case, or false if there were problems.
- #
- # The QuitSequence task takes the CPU from the appName as the front process through
- # quitting the app, verifying each milestone on the way. See the default endpoint
- # below. The application must disappear from the process menu for a success,
- # although the Finder may not become active if the test involves multiple apps.
- #
- # testN := { testType, 'appName', 'appCreator', 'appFolder',
- # {launchParameters}, {theLaunchSequence}, {theQuitSequence} }
- # launchParameters :=
- # 'FPU': Skip if target does not have an FPU
- # '32Bit': Skip if target is using 32-bit addressing
- # '68040 Caches': Skip if target has a 68040 and its caches are on
- # 'QuickTime': Skip if target is not running QuickTime
- # 'noCreatorLaunch': Skip if method is 'agentVUFG' or'agentVUBG' and this
- # is present. If method is 'auto' then use 'Find File'.
- # 'bgLaunchOK': Skip if method is a background launch and this is not present.
- # Most apps are not made to launch into the backgound so you
- # need to qualify each one thouroughly before allowing it.
- # 'UserSkipRequest': Skip because someone upstairs said so.
- # 'SNConflict': The application uses network based serial number copy
- # protection. If UsingArbitrator() is true, register the
- # application with the Arbitrator before launching. The
- # Arbitrator will give permission to launch if no other
- # actors have registered first. If they have, wait for one
- # minute and try again. If UsingArbitrator() is false, ignore
- # this parameter.
- # 'PPC': Skip if target is not a PowerPC
- # {'bitDepth',{restrictedBitDepths}}: This parameter tells the LQ Engine not
- # to launch if the target bitdepth is not in the list of
- # restricted bitdepths. The possible values are 1, 2, 4, 8,
- # 16, and 32. For example, {'bitDepth',{8,16,32}} will not
- # launch unless the target is set to 8, 16 or 32 bits per
- # pixel, corresponding to 256, thousands and millions of
- # colors. The other bitdepths (1,2,4) would be considered
- # "bad" bitdepths and for those, the app would be skipped.
- # A "bad" bit depth is one that blocks the application
- # from performing its normal launch sequence. This
- # can be a crash, or an alert that asks to change the
- # bit depth or quit. If an alert says "bit depth x will
- # work but not as well", and it does not crash, that is
- # not a "bad" bit depth and you should script around it.
- # Test defs *should* be executed if the application can
- # handle non-optimal bit depths without crashing or quitting.
- # Use the {'bitDepth',{}} parameter to avoid known crashes and
- # problems that can affect other apps or the system, or
- # until you have scripted the non-optimal bit
- # depths with conditionals.
- # NORMALLY, APPLICATIONS DO NOT CHANGE THE BIT DEPTH
- # OR SWITCH BETWEEN COLORS AND GRAYS.
- # 'MMM': Skip if app does not launch with Modern Memory Manager on.
- # 'EBBE': Skip if app crashes with EvenBetterBusError,a system
- # extension to help catch renegade references to NIL.
- # '68K': Skip if Target is PPC, i.e., launch only if target is a 68K.
- # This parameter should be the first one in a parameter list
- # due to some apps won't launch properly otherwise.
- # 'MaxT0': For Maxwell tier 0 app. Yet to be implemented.
- #
- # exampleAppSequence := { awaitDesc[, doItem][, awaitDesc][, doItem]… }
- # awaitDesc: descriptor: await_presence
- # integer: wait this long
- # list: conditional sub-sequence
- # string: '': do nothing
- # other: log the string as cause of failure and return false
- #
- # doItem: descriptor: select
- # string: '<': select the previous awaitDesc
- # '>': wait for the previous awaitDesc to disappear
- # '': do nothing
- # other: log the string as cause of failure and return false
- # list: flexible selector; first item is the actionType, second and on
- # contain additional info as defined by the actionType
- # 'type_keys': 2nd item: type_keys() list
- # 3rd item: optional log as purpose of type_keys List
- # 'fieldSequence':2nd item: list of strings to be typed with a
- # tab after each one, for filling dialog fields
- # 'key_eq': 2nd item: key_eq() string
- # 'move_mouse': 2nd item: move_mouse() list
- # 3rd item: optional log as purpose of move_mouse List
- # 'fieldSequence':2nd item: list of strings to be typed with a
- # tab after each one, for filling dialog fields
- # 'SFGet': 2nd item: string to type followed by returnKey
- # 'SFPut': 2nd item: string to type followed by returnKey
- # if Replace button appears, click it
- # 'SFPutNewName': 2nd item: string to type followed by returnKey
- # if Replace button appears, make a random name until
- # the replace button does not appear
- #
- #
- # theQuitSequence := { awaitDesc[, doItem][, awaitDesc][, doItem]… }
- # awaitDesc: descriptor: await_presence
- # list: conditional sub-sequence
- # doItem: descriptor: select
- # '<': select the most recent awaitDesc
- # '': do nothing
- # string: type it followed by returnKey, select [button t:'Replace'] if it exists
- # add conditional {[application t:appName],[menuItem t:'Quit' m:'File']}
- # as a default endpoint
- # Contains:
- # CheckLaunchQuit()
- # LaunchApplication()
- # CheckLaunchDialog()
- # QuitSequence()
- # AppSequence()
- # LQWaitItem()
- # GetLQWaitItemTimeout()
- # LQDoItem()
- # Quit_Apps()
- # AwaitAppQuit()
- # AcquireApplication()
- # ReleaseApplication()
- # FindFile()
- #
- # History:
- # Date: By: Changes:
- # 12/15/92 SBR Created based on script by Al Alamsetty and Alan Masri
- # 03/22/94 SBR Many changes after code review, e.g. new library header
- # 06/17/94 GK (Gary Kratzer) Added PPC launch parameter.
- # 11/27/94 SBR Fix for Radar 1195293 in CheckLaunchQuits().
- # 04/10/95 SBR CheckLaunchQuits(): Added Phoenix reporting. Added -1096 error handler.
- # Better organization and comments for test def execution.
- #
- # LaunchApplication: Extensive modifications to fix Radar problems
- # 1172264, 1193530. Added check for -1096 launch error. Added 'EBBE'
- # launchparam. Changed '68040 caches' skip string to request removal
- # of the test def.
- #
- # QuitSequence: Uses ReleaseApplication().
- #
- # AppSequence: Removed 'restart' selectAction, added better reporting
- # for move_mouse and type_keys. Moved code for waitItem and doItem
- # into separate tasks. Changed descString from a constructed string
- # to the descriptor as it appears in the sequence. Now reports the
- # ordinal of the sequence item that failed.
- #
- # Added AcquireApplication() and ReleaseApplication().
- #
- # 08/02/95 SBR Radar 1270966: added AwaitAppQuit(), new code in Quit_Apps(),
- # changes in QuitSequence()
- # Radar 1272949: changes to LQWaitItem()
- # Radar 1274920: added GetLQWaitItemTimeout()
- # Radar 1274921: AppSequence() default v_level from 5 to 4
- # Radar 1270963: changes to QuitSequence()
- # Radar 1271126: added 'MMM' skip reason
- # Radar 1124475: added 'BitDepth n' skip reason
- # Radar 1274923: advise to remove 32-bit unclean apps
- # Radar 1274930: 'FPU' skip string more descriptive.
- # 09/12/96 Masa LaunchApplication: Added FindFile Launch method
- # 09/27/96 BRL Added SPEC Exception handling
- # 10/23/96 Masa CheckLaunchDialog: added code to improve treatment of unexpected dialogs.
- # 10/28/96 Bry/Masa LaunchApplication: Radar 1124475
- # Masa/Bry Radar 1390088 Skip test with inadequate bitdepth
- # 10/29/96 Masa CheckLaunchDialog: fixed matching problem in 'Get static dialog text' code segment.
- # FindFile: debug.
- # 11/08/96 Masa FindFile: modified await_absence for 'Find File≈'
- # 12/02/96 Masa Radar 1185532: unexpected dialogs, fixed
- # Radar 1274812 crash detection through try/catch
- # Radar 1304881 LQAssist.vu documentation
- # Radar 1369899 added 'btdepth' 'MMM' 'EBBE' '68K' 'MaxTO'
- # Radar 1271320 Action 1.0.4 test definition
- # Radar 1606877 FindFile() search criteria: 'name is'
- # instead of 'name contains'
- # 12/05/96 Masa FindFile: Changed logic 'gItemNotFound' to 'gItemFound' to eliminate
- # misleading comment after 'app not found on selected volume(s)'
- # 12/05/96 Masa Radar 1606877 FindFile() search criteria: 'name is'
- # LaunchApplication: Changed Logic: gItemNotFound to gItemtFound.
- # 12/06/96 Masa Radar 1610060 Misleading FindFile() message after file not found.
- # 12/10/96 SBR LQDoItem: Changed 'await_absence(previousDesc,,,,6)' to
- # 'await_absence(previousDesc,waitTime,,,6)' in .
- # CheckLaunchDialog: Changed await_absence(previousDesc to use waitTime instead of default
- # 12/10/96 SBR/Masa FindFile: Added wait(0,0,0,60) in FindFile() at 'launch' def to ensure option
- # key is taken into account.
- # Changed '(await_absence([window t:/Find File' to
- # '(await_absence([application t:/Find File'
- # 12/17/96 Masa CheckLaunchQuit: Fix Radar 1378111
- # SBR/Masa Fix Radar 1613887
- # 01/30/97 SBR Deleted older exception code and comments.
- # 01/31/97 SBR Changed AIQ LaunchQuits.vuLib to LaunchQuit Test Defs.vuLib.
- # Changed 'test case' to 'test def'; 'TC' to 'TD'.
- # 01/31/97 SBR Retired VUAidFKEY after many years of valuable service.
- #########################################################################
- #########################################################################
- Libraries
- #Clouseau libraries
- "Additions.lib",
- "Clouseau.lib",
- "Report.lib",
- "TargetControl.lib",
- "VUAid.lib",
- "VUAid.tool",
-
- #SPEC libraries
- "FileTool.vuLib",
- "Results Express.lib",
- "Globals.lib",
- "TCS.lib",
- "ExceptionHandling.lib",
-
- #Launchquit libraries
- "Arbitrator.vu",
- "LaunchQuit Test Defs.vulib",
- "Dev Launchquits",
- "LQCustom.lib";
-
-
- #########################################################################
- # task CheckLaunchQuit( testType, RunOnlyTheseTests := {}, SkipTheseTests := {},
- # engineParameters := {}, v_level := 4)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: The test def engine for LaunchQuit Test Defs. Calls
- # LaunchApplication() and QuitSequence() to do the real work.
- # Parameters: testType: maximum testType to execute for this engine run
- # RunOnlyTheseTests:
- # empty list: run all TDs except those in SkipTheseTests
- # list of strings: run this subset except those in SkipTheseTests
- # SkipTheseTests: never run these, they are likely to stop the run
- # engineParameters: Misc items to modify engine behavior
- # v_level: minimum verbosity level for this task to log itself in detail
- # Returns: nothing
- # Examples: CheckLaunchQuit(1,true,{'MacDraw Pro','Swamp Gas'});
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 11/15/92 SBR Created
- # 05/27/93 SBR Removed test def list parameter. Now we use gBigTCList global
- # 08/12/93 SBR Removed gBigTCList global. Now we use GetTestDef lookup task.
- # 11/10/93 SBR GetTestDef parameters changed. Removed storeTCHistory;
- # the lookup task stores its own history in a private global
- # 11/10/93 SBR Renamed gtcResult to theTestDef because of the above reason;
- # the lookup task returns only the test def now.
- # 11/10/93 SBR Added support for resumeOffset.
- # 11/10/93 SBR Added EPushHandler/EPopHandler for -1104 errors.
- # 03/21/94 SBR Moved RCloseTest() to occur before Arbitrator disconnect
- # 03/21/94 SBR Added VUAid('Quit') if launchMethod ~= /VUAid2≈/
- # 06/27/94 SBR Added UnRegisterApplication to launch fail path. It was
- # previously only in QuitSequence(), and not done if launch failed.
- # 11/27/94 SBR Fix for Radar 1195293.
- # 04/10/95 SBR Added Phoenix reporting. Added -1096 error handler. Better
- # organization and comments for test def execution.
- # 12/17/96 SBR/Masa Fix Radar 1378111
- # SBR/Masa Fix Radar 1613887
- # 01/30/97 SBR Retired VUAidFKEY (sniff).
- #########################################################################
- task CheckLaunchQuit( testType, RunOnlyTheseTests := {}, SkipTheseTests := {},
- engineParameters := {}, v_level := 4)
- begin
- global gUsingPhoenix, gLQTCSBeginTime;
-
- ##SBR Debug stuff: checking how much time we waste waiting for things that don't happen
- # global gWastedTime := 0;
-
- AddExceptionHandler(-1100, {TASK EH_CrashRecover, {'CheckLaunchQuit',2,15},0});
- AddExceptionHandler(-1104, {TASK EH_CrashRecover, {'CheckLaunchQuit',2,15},0});
- AddExceptionHandler(-1105, {TASK EH_CrashRecover, {'CheckLaunchQuit',2,15},0});
- AddExceptionHandler(-1096, {TASK EH_CrashRecover, {'CheckLaunchQuit',2,15},0});
-
- if isMember('UsingArbitrator', engineParameters);
- begin
- if not PrepareArbitrator() # launch the Arbitrator external tool
- begin
- RStatus("Please make sure the Arbitrator external tool is on the host.",1);
- RStatus("If it is there, you may need to re-build the desktop.",1);
- exit;
- end;
- end;
-
- gUsingPhoenix := assoc('Phoenix', engineParameters);
- if gUsingPhoenix
- begin
- if typeOf(gUsingPhoenix) = 'list'
- begin
- NewMatrix({ { "MatrixName", gUsingPhoenix[2] } });
-
- SuiteStart(gUsingPhoenix[1], , '2.1.1', gUsingPhoenix[2]);
- gUsingPhoenix := true;
- end;
- else if typeOf(gUsingPhoenix) = 'string'
- begin
- SuiteStart(gUsingPhoenix, , '2.1.1');
- gUsingPhoenix := true;
- end;
- else
- begin
- SuiteStart('LaunchQuit Engine', , '2.1.1' );
- end;
- end;
-
- engineStartTime := time_list(_Match([time]));
-
- timers := assoc('timers', engineParameters);
- if timers
- begin
- markTime := engineStartTime;
- if isMember('TDCore',timers)
- TDCoreTimerOn := true; #time for each LaunchQuit
- if isMember('mark',timers)
- markTimerOn := true; #time for test def (+ overhead)
- timers := true;
- end;
-
- ROpenTest("LaunchQuit Engine");
-
- try
- match[target t:?tName z:?tZone];
- catch theError
- ExceptionDispatcher(theError,,{"Match 1 in CheckLaunchQuit", {testType, RunOnlyTheseTests,
- SkipTheseTests, engineParameters, v_level}});
-
- firstTDOrdinal := 1; # set up skipping/resuming mechanism
- waitingForName := false;
- resumeAction := assoc('resumeThisTD', engineParameters);
- resumeOffset := assoc('resumeTDOffset', engineParameters);
- iterateTD := assoc('iterateTD', engineParameters);
-
- GetTestDef := assoc('GetTestDefTask', engineParameters);
- specialParameters := assoc('specialParameters', engineParameters);
- randomDeal := assoc('randomDeal', engineParameters);
- if randomDeal
- nextTDcommand := 'randomDeal';
- else
- nextTDcommand := 'nextTD';
- doCustomTask := assoc('doCustomTask', engineParameters);
-
- # 09/29/94 SBR: Auto-resuming was removed when we switched to the Arbitrator external tool,
- # which does not support the resume feature. One day it may return, but first we have to
- # define what "resume" means in the larger context of a bundle of tests (a la Tracs).
- #
- # if UsingArbitrator() and resumeAction
- # begin
- # if resumeAction = 'Reset'
- # begin
- # send_list('Arbitrator', {'resumeReset'});
- # if receive_list('Arbitrator', 2, 120) <> { tName,'resumeReset' }
- # begin
- # RStatus("Arbitrator did not respond to 'resumeReset', so resume feature is off.",1);
- # resumeAction := false;
- # end;
- # end;
- # else if resumeAction ~= /Arb≈/ # Arbitrator returns name of TD to resume
- # begin
- # send_list('Arbitrator', {'resume'});
- # temp := receive_list('Arbitrator', 2, 120);
- # if temp[1] = tName # temp[2] = 'resumeReset' or "{TDName}"
- # begin
- # resumeAction := temp[2];
- # if resumeAction = 'resumeReset'
- # resumeAction := false;
- # else begin
- # if resumeOffset
- # temp := " offset by {resumeOffset}";
- # else
- # temp := "";
- # RStatus("Resuming script execution at '{resumeAction}'{temp}.",1);
- # waitingForName := true;
- # end;
- # end;
- # else
- # begin
- # RStatus("Received bad message from Arbitrator ({temp}), so resume feature is off.",1);
- # resumeAction := false;
- # end;
- # end;
- # end;
-
- # The next section uses the GetTestDef task reference variable, which is passed to
- # the CheckLaunchQuit task through engineParameters. The actual method of storing
- # and looking up the test defs is not visible to the caller. It is defined by the
- # same entity that passes in the GetTestDef value. However, in all cases the task
- # parameters and return values are the same. The three parameters are partialName,
- # specialParameters, and resetTDHistory.
- #
- # PartialName can be the name of the test def, or a specially defined string which
- # causes the lookup task to pick a test def in some special way. The three strings
- # always available are: 'NextTD', which gets the next test def based on its
- # privately stored history; 'random', which picks a test def randomly; and
- # 'randomDeal' which also picks a test def randomly, but uses TDHistory to prevent
- # repeating until all of the test defs have been used.
- #
- # SpecialParameters is used for any purpose specific to the kind of test defs the
- # lookup task is looking for. For LaunchQuit Script, use specialParameters to limit
- # the search to those test defs whose app parameters list contains all the items in
- # specialParameters. For example, passing { 'FPU','SNConflict' } in specialParameters
- # causes the lookup task to search for the first occurance of a test def with both
- # 'FPU' and 'SNConflict' in its app parameters list. The app parameters list is the
- # 5th item in a LaunchQuit test def, and it may contain other items.
- #
- # The resetTDHistory parameter, if true, clears the stored history of the lookup task.
- # To allow implementation of cool features without additional effort on the caller's
- # part, the lookup task stores codes representing the previous test def returned, in
- # an internally defined global variable. The caller does not need to know the contents
- # of this list but it should be documented in the comments of the lookup task. For
- # example, when choosing test defs randomly with the LaunchQuit engine, the global
- # may contain a list of integers representing applications eligible to be picked.
- # This list shrinks over time, but the caller is not aware of this.
- # If the resetTDHistory parameter contains a list, its value is stored directly into
- # the global variable. This a way to test the lookup task as well as begin testing
- # in the middle of the list.
-
- badResumeMsg := "Could not resume a test def name containing '{resumeAction}'";
-
- RunOnlyTheseIndex := 0; # get the first test def by name matching, or just get the first one
- if RunOnlyTheseTests
- begin
- if resumeAction # fixes Radar #1195293
- begin
- # look for resume item by exact name (fast but not 100% sure to find it)
- RunOnlyTheseIndex := isMember(resumeAction, RunOnlyTheseTests);
-
- RunOnlyTheseIndex := RunOnlyTheseIndex + resumeOffset;
- if (RunOnlyTheseIndex > card RunOnlyTheseTests) or (RunOnlyTheseIndex = resumeOffset)
- begin
- RStatus("{badResumeMsg}.",1);
- RStatus("Please make sure the string in Resume_Last_Run exactly matches",1);
- RStatus("one of the strings in Run_Only_These_Tests",1);
- exit;
- end;
-
- resumeAction := false;
- end;
- else
- begin
- RunOnlyTheseIndex := RunOnlyTheseIndex + 1;
- end;
-
- # get the next test def from the Run_Only_These_Tests list (a script parameter)
- theTestDef := call(GetTestDef, RunOnlyTheseTests[RunOnlyTheseIndex], specialParameters, true);
- ### Masa 12/17/96 Added to fix Radar 1378111
- while (not theTestDef) and (RunOnlyTheseIndex <= card RunOnlyTheseTests)
- begin
- resultString := "∂"{RunOnlyTheseTests[RunOnlyTheseIndex]}∂" not found in the data base; check spelling.";
- rResult('incomplete', resultString); # report the result of this test def
- RunOnlyTheseIndex := RunOnlyTheseIndex + 1;
- if RunOnlyTheseIndex <= card RunOnlyTheseTests
- theTestDef := call(GetTestDef, RunOnlyTheseTests[RunOnlyTheseIndex], specialParameters, true);
- end;
- ### end Radar 1378111 code
- end;
- else
- begin
- # get the next test def from the entire database
- theTestDef := call(GetTestDef, nextTDcommand, specialParameters, true);
- end;
-
- while theTestDef # MAIN TEST DEF LOOP
- begin
- if resumeAction # go to the resume TD by name in first iteration
- begin
- theTestDef := call(GetTestDef, resumeAction, specialParameters, true);
- if not theTestDef
- begin
- RStatus("{badResumeMsg}.",1);
- exit;
- end;
-
- else for i := 1 to resumeOffset # fixes Radar 1119463
- begin
- theTestDef := call(GetTestDef, "nextTD", specialParameters, false);
- if not theTestDef
- begin
- RStatus("{badResumeMsg}, offset by {resumeOffset}.",1);
- exit;
- end;
- end;
- resumeAction := false; # only use resume feature on first iteration
- end;
-
- thisTestType := theTestDef[1]; # the type of theTestDef
- appName := theTestDef[2]; # the application to launch = the test name
-
- skipThisApp := false;
- if SkipTheseTests
- begin
- temp := 1;
- while (temp <= card SkipTheseTests) and not appIsExcepted
- begin
- shortName := SkipTheseTests[temp];
-
- if appName ~= /{shortName}≈/ # is this a TD to skip?
- begin
- skipThisApp := true;
- SkipTheseTests := remove(temp, SkipTheseTests); # quicker next time
- end;
- else temp := temp + 1;
- end;
- end;
-
- if (thisTestType > testType); # reasons to skip this TD without logging
- else for i := 1 to iterateTD # OK to continue final checks
- begin
- # if UsingArbitrator()
- # send_list('Arbitrator', {'beginTD', appName});
- appSig := theTestDef[3]; # creator (signature) to launch with Agent VU
- appDir := theTestDef[4]; # parent directory
- launchParams := theTestDef[5]; # modifications/requirements of launch
- if skipThisApp
- ### SBR/Masa 12/17/96 Fixed for Radar 1613887
- launchParams := {'UserSkipRequest'} + launchParams;
- launchSeq := theTestDef[6]; # how to get to a new blank document
- quitSeq := theTestDef[7]; # how to quit
-
- launchMethod := assoc('launchBy', engineParameters);
-
- if TDCoreTimerOn
- TDCoreStartTime := _Match([time]);
-
- ################################################################################
- # Here it is, the big Launch followed by the big Quit. Everything else is fluff.
-
- AddExceptionHandler(-1100, {TASK EH_CrashRecover, {appName,2,15},0});
- AddExceptionHandler(-1104, {TASK EH_CrashRecover, {appName,2,15},0});
- AddExceptionHandler(-1105, {TASK EH_CrashRecover, {appName,2,15},0});
- AddExceptionHandler(-1096, {TASK EH_CrashRecover, {appName,2,15},0});
-
- ##### LAUNCH THE APPLICATION
- LQResult := LaunchApplication(appName, appSig, appDir, launchMethod, launchParams, 10 );
-
- ##### DO THE LAUNCH SEQUENCE
- if LQResult[1] = 'pass' # application passed basic launch
- begin
- launchMethod := LQResult[2]; # LaunchApplication can use alternate methods
-
- #default if launch sequence is empty or even number, i.e. no waitItem at the end
- if not launchSeq or (card launchSeq) = (card launchSeq/2)*2
- launchSeq := launchSeq + {[window t:/≈Untitled≈/]};
-
- if AppSequence(appName, launchSeq, false)
- RAddResult("completed launch sequence");
- else
- begin
- theTarget := _Match([target]);
- if not theTarget
- moreAddResult := " - target crashed";
- else
- moreAddResult := '';
-
- RAddResult("failed launch sequence {moreAddResult}");
- LQResult := {'fail',"'{appName}' failed during the launch sequence"};
- end;
- end;
-
- ##### DO THE CUSTOM TASK
- if (LQResult[1] = 'pass') and doCustomTask # application passed launch sequence
- begin
- theResult := LQCustomTask(); # see LQCustom.lib
- if theResult
- RAddResult("The custom task executed correctly.");
- else
- begin
- RAddResult("The custom task did not execute correctly.");
- LQResult := {'fail',"'{appName}' failed during the custom task"};
- end;
- end;
-
- ##### QUIT THE APPLICATION
- if LQResult[1] = 'pass' # custom task passed (if it was called)
- begin
- quitResult := QuitSequence(appName, quitSeq);
-
- if (quitResult[1] = 'pass') # everything worked!!
- LQResult:= {'pass',"{appName} LaunchQuit by {launchMethod}"};
- else
- LQResult := quitResult;
- end;
-
- ##### CHECK FOR FAILURE
- switch LQResult[1]
- begin
- case 'pass':
- begin
- tcPassed := true;
- end;
-
- case 'incomplete':
- begin
- tcPassed := false;
- # No need to un-register because it was skipped
- end;
-
- case 'fail':
- begin
- tcPassed := false;
- Quit_Apps({appName},false); # quit this app any possible way
-
- if UsingArbitrator()
- begin
- # Un-register the app for SNConflict. If we are using the Arbitrator at all,
- # we send every app name to ReleaseApplication() and let that task decide for
- # us if the application is registered or not. We do this because the actual
- # registration mechanism may change, so keep it in wrapper tasks.
- # If the app was not registered, ReleaseApplication() returns true.
-
- if not ReleaseApplication( appName )
- return {'incomplete', 'CheckLaunchQuit (fail): ReleaseApplication failed.'};
- end;
- end;
- end;
-
- RemoveExceptionHandler(-1104);
- RemoveExceptionHandler(-1100);
- RemoveExceptionHandler(-1105);
- RemoveExceptionHandler(-1096);
- ################################################################################
-
- timerString := "";
- if timers
- begin
- if TDCoreTimerOn
- timerString := "(" + time_str( time_sub(_Match([time]), TDCoreStartTime) ) +
- timerString + ") ";
-
- if markTimerOn
- begin
- markTimeInterval := time_sub(_Match([time]), markTime);
-
- markTime := time_add(markTimeInterval,markTime);
- timerString := "(" + time_str( markTimeInterval ) + timerString + ") ";
- end;
- end;
-
- # If we did not skip, check if there is a MacsBug macro set up. If there
- # is, then always look for a crash log even if the test "passed". If the
- # test failed or if a crash log exists, log a full report, and
- # reset the EveryTime macro. Otherwise just print the "verified" line.
-
- if not (LQResult[2] ~= /≈skip≈/)
- begin
- if setMacsBugMacro('read')
- begin
- mbLogName := MacsBugLog(appName);
- if mbLogName
- begin
- RAddResult("MacsBug log is named {mbLogName}");
- setMacsBugMacro('restore');
- if tcPassed
- LQResult:= {'fail',"{appName} LaunchQuit passed, but found a MacsBug Log"};
- tcPassed := false;
- end;
- end;
- end;
-
- if gUsingPhoenix
- begin
- _Match([mouse]);
-
- TCSDuration := LastCommandTargetTime() - gLQTCSBeginTime;
-
- switch LQResult[1]
- begin
- case 'pass':
- begin
- # TCSEnd(pTCSId := {}, pResultCode := '', pErrStr := '', pTCSVal := 0, pTCSStr := '', pCommentStr := '', pExceptionFlag := '')
- TCSEnd({ launchTCSNumber, global kTCSetLaunch }, 1,,TCSDuration,appName,LQResult[2]);
- end;
- case 'fail':
- begin
- TCSEnd({ launchTCSNumber, global kTCSetLaunch }, 0, LQResult[2],TCSDuration,appName);
- end;
- case 'incomplete':
- begin
- TCSEnd({ launchTCSNumber, global kTCSetLaunch }, -1, LQResult[2],TCSDuration,appName);
- end;
- end;
- end;
-
- LQResult := { LQResult[1], "{timerString}" + LQResult[2] }; # add timer info
-
- if not tcPassed
- RPushVerbosity(3);
- rResult(LQResult[1], LQResult[2]); # report the result of this test def
- if not tcPassed
- RPopVerbosity();
-
- end; # for i := 1 to iterateTD (implies theTestDef[1] <= testType)
-
- if RunOnlyTheseTests # get the next test def by name matching, else just get the next one
- begin
- RunOnlyTheseIndex := RunOnlyTheseIndex + 1;
-
- if RunOnlyTheseIndex <= card RunOnlyTheseTests
- begin
- # get the next test def from the Run_Only_These_Tests list (a script parameter)
- theTestDef := call(GetTestDef, RunOnlyTheseTests[RunOnlyTheseIndex],
- specialParameters, true);
- ### Masa 12/17/96 Added to fix Radar 1378111
- while (not theTestDef) and (RunOnlyTheseIndex <= card RunOnlyTheseTests)
- begin
- resultString := "∂"{RunOnlyTheseTests[RunOnlyTheseIndex]}∂" not found in the data base; check spelling.";
- rResult('incomplete', resultString); # report the result of this test def
- RunOnlyTheseIndex := RunOnlyTheseIndex + 1;
- if RunOnlyTheseIndex <= card RunOnlyTheseTests
- theTestDef := call(GetTestDef, RunOnlyTheseTests[RunOnlyTheseIndex], specialParameters, true);
- end;
- ### end Radar 1378111
- end;
- else
- theTestDef := {};
- end;
- else
- begin
- theTestDef := call(GetTestDef, nextTDcommand, specialParameters, false);
- end;
- end; # while theTestDef # MAIN TEST DEF LOOP
-
- ##SBR Debug stuff
- # global gWastedTime;
- # println ;
- # println " ••Wasted {gWastedTime} seconds in conditional sub-sequences!••";
- # println ;
-
- RCloseTest();
-
- if UsingArbitrator() # clean disconnect from the Arbitrator
- begin
- # send_list('Arbitrator', {'resumeReset'});
- # receive_list('Arbitrator', 2, 60);
- ReleaseArbitrator();
- end;
-
- if launchMethod ~= /VUAid2≈/ # quit the external tool if we used it
- VUAid('Quit');
-
- RemoveExceptionHandler(-1104);
- RemoveExceptionHandler(-1100);
- RemoveExceptionHandler(-1105);
- RemoveExceptionHandler(-1096);
-
- if gUsingPhoenix
- begin
- SuiteEnd(1);
- end;
- end;
-
-
- #########################################################################
- # task LaunchApplication( appName, appSig, appDir, launchBy,
- # launchParams, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Launch an application by a particular method, unless the target
- # is not capable of it. Use special parameters to ensure the application
- # launches only under the right conditions.
- # Parameters: appName: Exact name of the application to launch.
- # appSig: The creator or signature of the application.
- # appDir: Exact name of the application's folder.
- # CAUTION: Across all volumes on the target, these three values
- # should be unique, to insure zero probability that the
- # wrong files are launched, under all conditions. Other
- # Findable items should not contain their names. If appSig
- # is not unique, you need to put 'noCreatorLaunch' in
- # launchParams to prevent launching the wrong application.
- # launchBy: Method to use for launching
- # 'AgentVUFG': Launch by creator into the foreground using Agent VU.
- # CAUTION: Agent VU 2.0, 2.0.1 and 2.1 will not launch an app if
- # the preferred size is not available. Since Agent VU
- # uses the creator, appSig should be unique across all
- # target volumes.
- # 'AgentVUBG': Launch by creator into the background using Agent VU.
- # Since most applications do not launch properly into
- # the background, this method is not allowed unless
- # launchParams contains 'bgLaunchOK'.
- # 'Find File': Launch Find File and find appName. Uses option-
- # doubleClick to quit Find File before launching the app.
- # This method is sure if the names are unique.
- # 'Finder': Twitch to Finder and Find appName. Type command-O
- # while pressing the option key to close appDir window.
- # This method is slow but sure if the names are unique.
- # 'auto': Use 'agentVUFG', but if this is fails use 'Find File'.
- # Failures are: launchParams contains 'noCreatorLaunch',
- # Agent VU fails to locate the application, Agent VU
- # fails to launch due to lack of space.
- # 'VUAid2FG': Launch by appName into foreground using VUAid External tool.
- # 'VUAid2BG': Launch by appName into background using VUAid External tool.
- # 'VUAidFKEY': (Obsolete method; do not use) Use the VUAid FKEY to launch by appName
- # CAUTION: As of version 1.0.9, the VUAid FKEY does not return an
- # error if the application does not have enough memory
- # space to launch. It returns an error if it can not find
- # the application by name, however.
- # launchParams: reasons to skip or modify launching and log the reason
- # 'FPU': Skip if target does not have an FPU
- # '32Bit': Skip if target is using 32-bit addressing
- # '68040 Caches': Skip if target has a 68040 and its caches are on
- # 'QuickTime': Skip if target is not running QuickTime
- # 'noCreatorLaunch': Skip if method is 'agentVUFG' or'agentVUBG' and this
- # is present. If method is 'auto' then use 'Find File'.
- # 'bgLaunchOK': Skip if method is 'agentVUBG' and this is not present.
- # Most apps are not made to launch into the backgound so you
- # need to qualify each one thouroughly before allowing it.
- # 'UserSkipRequest': Skip because someone upstairs said so.
- # 'SNConflict': The application uses network based serial number copy
- # protection. If UsingArbitrator() is true, register the
- # application with the Arbitrator before launching. The
- # Arbitrator will give permission to launch if no other
- # actors have registered first. If they have, wait for one
- # minute and try again. If UsingArbitrator() is false, ignore
- # this parameter.
- # 'PPC': Skip if target is not a PowerPC
- # {'bitDepth',{restrictedBitDepths}}: This parameter tells the LQ Engine not
- # to launch if the target bitdepth is not in the list of
- # restricted bitdepths. The possible values are 1, 2, 4, 8,
- # 16, and 32. For example, {'bitDepth',{8,16,32}} will not
- # launch unless the target is set to 8, 16 or 32 bits per
- # pixel, corresponding to 256, thousands and millions of
- # colors. The other bitdepths (1,2,4) would be considered
- # "bad" bitdepths and for those, the app would be skipped.
- # A "bad" bit depth is one that blocks the application
- # from performing its normal launch sequence. This
- # can be a crash, or an alert that asks to change the
- # bit depth or quit. If an alert says "bit depth x will
- # work but not as well", and it does not crash, that is
- # not a "bad" bit depth and you should script around it.
- # Test defs *should* be executed if the application can
- # handle non-optimal bit depths without crashing or quitting.
- # Use the {'bitDepth',{}} parameter to avoid known crashes and
- # problems that can affect other apps or the system, or
- # until you have scripted the non-optimal bit
- # depths with conditionals.
- # NORMALLY, APPLICATIONS DO NOT CHANGE THE BIT DEPTH
- # OR SWITCH BETWEEN COLORS AND GRAYS.
- #
- # v_level: verbosity level for log output
- # Returns: success: true
- # failure: {'incomplete', "Skipped '{appName}' - {skipReason}"}
- # Example: LaunchApplication('TeachText 7.0@', 'ttxt', 'TeachText 7.0ƒ');
- # LaunchApplication('ResEdit™ 2.1.1@', 'RSED', 'ResEdit™ 2.1.1ƒ','auto',
- # {'noCreatorLaunch'})
- # Assumptions: VU 2.1.
- # CloseView is removed entirely and never used, otherwise cmd-opt-O
- # will not work. This is used to launch applications in the Finder.
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # ??/??/92 SBR Created as launchSequence
- # 10/10/93 SBR Changed to LaunchApplication, removed sequence handler
- # 06/17/94 GK Added PPC launch parameter.
- # 11/11/94 SBR Changed launchparam check to use a case statement.
- # 04/10/95 SBR Extensive modifications to fix Radar problems 1172264, 1193530.
- # Added check for -1096 launch error. Added 'EBBE' launchparam.
- # Changed '68040 caches' skip string to request TD removal.
- # 08/03/95 SBR Added Phoenix reporting.
- # Radar 1274923: '32Bit' skip string requests TD removal.
- # Radar 1274930: 'FPU' skip string more descriptive.
- # Radar 1271126: add 'MMM' skip string.
- # Radar 1124475: add 'Bitdepth n' skip string.
- # 09/12/96 Masa Added FindFile w/exception handling
- # 10/23/96 Masa improved unexpected dialog treatment
- # 10/28/96 Bry/Masa Radar 1124475
- # 12/05/96 Masa Changed Logic: gItemNotFound to gItemFound
- # 12/20/96 SBR Changed Logic: wait until just before launch to call AcquireApplication()
- # 01/30/97 SBR Removed "appDir" code in Find File logic
- # 01/30/97 SBR Retired VUAidFKEY (sniff).
- #########################################################################
- task LaunchApplication( appName, appSig, appDir, launchBy, launchParams,
- appWait := 10, v_level := 4)
- begin
- global gUsingPhoenix, gLQTCSBeginTime;
- global kTCSetLaunch;
-
- global gItemFound;
- global gDialogWindow;
- global gOtherUnexpectedFlag;
-
- kQuitWait := 30;
-
- badLaunch := {'fail',"'{appName}' did not launch properly"};
-
- noCreatorLaunch := isMember('noCreatorLaunch',launchParams);
- if noCreatorLaunch
- launchParams := Remove(noCreatorLaunch, launchParams);
-
- if launchBy = 'auto'
- begin
- if noCreatorLaunch
- begin
- launchBy := 'Find File';
- end;
- else
- launchBy := 'agentVUFG';
- end;
-
- launchTCSNumber := isMember(launchBy, {'AgentVUFG', 'AgentVUBG', 'Finder', 'VUAid2FG', 'VUAid2BG',
- 'VUAidFKEY', 'Find File'});
-
- if not launchTCSNumber or launchBy = "VUAidFKEY"
- begin
- RAddResult("'{launchBy}' is an invalid or obsolete launch method.");
- return badLaunch;
- end;
-
- curApName := _Match([application]).t; # to check for wrong app/BG switch
- if launchBy ~= /≈BG/
- begin
- try
- match [menu o:$menuOrds];
- catch theError
- ExceptionDispatcher(theError,,{"Match 1 in LaunchApplication()", {appName, appSig, appDir,
- launchBy, launchParams, appWait, v_level}});
-
- processMenu := card menuOrds;
-
- try
- match [menuItem m:processMenu t:$curApList]!; # store current items in process menu
- catch theError
- ExceptionDispatcher(theError,,{"Match 2 in LaunchApplication", {appName, appSig, appDir,
- launchBy, launchParams, appWait, v_level}});
- end;
-
- if gUsingPhoenix
- begin
- launchTCSNumber := launchTCSNumber + 4; # SPEC libs use 1-4 already
- gLQTCSBeginTime := LastCommandTargetTime(); # start TCS duration ( >= LQ duration )
- TCSStart({ launchTCSNumber, kTCSetLaunch },
- "LaunchQuit application by {launchMethod}");
- end;
-
- #don't launch if the parameters are not met (or wait if SNConflict)
- skipReason := '';
- arbResponse := '';
- #SBR 12/20/96 Changed for Radar 1615038
- SNConflict := false;
-
- # look for special restrictions or modifications for launch
- try
- begin
- # Added for Radar 1124475
- restrictedBitDepths := assoc('bitDepth', launchParams);
- if restrictedBitDepths
- begin
- curDepth := get_target_info('bit depth#');
- if not isMember(curDepth, restrictedBitDepths)
- throw "Current bitDepth ({curDepth}) is unacceptable. Only {restrictedBitDepths} are allowed.";
- end;
- for each launchParam in launchParams
- begin
- switch launchParam
- begin
- case 'FPU':
- begin
- if not get_target_info('fpu#')
- begin
- # better string for Radar 1274930
- skipReason := "680x0 FPU required";
- if get_target_info('processor') ~= /PPC≈/
- skipReason := skipReason + " (software FPU needed on PowerPC)";
- throw skipReason;
- end;
- end;
-
- case 'UserSkipRequest':
- begin
- throw "user request";
- end;
-
- case 'PPC':
- begin
- if not (get_target_info('processor') ~= /PPC≈/)
- throw "PowerPC processor required (will not run on 680x0)";
- end;
-
- case '68K': # SBR 02/20/95 added for Radar #1193530
- begin
- if not (get_target_info('processor') ~= /68≈/)
- throw "680x0 processor required (will not run on PowerPC)";
- end;
-
- case 'SNConflict':
- begin
- #SBR 12/20/96 Changed for Radar 1615038
- #if not AcquireApplication( appName )
- #throw "could not acquire a lock on {appName} from the Arbitrator";
- SNConflict := true;
- end;
-
- case 'QuickTime':
- begin
- if not get_target_info('QuickTime#')
- throw "QuickTime required";
- end;
-
- case '32Bit':
- begin
- # Radar 1274923: advise to remove 32-bit unclean apps
- if get_target_info('32#')
- throw "32-bit unclean: please remove this test def";
- end;
-
- case 'bgLaunchOK':
- begin
- bgLaunchOK := true;
- end;
-
- case '68040 Caches':
- begin
- throw "68040 cache unclean: please remove this test def";
- end;
-
- case 'EBBE':
- begin
- if get_target_info('EBBE')
- throw "known problems with EvenBetterBusError";
- end;
-
- case 'MMM':
- begin
- # Added for Radar 1271126
- # 0 is original 24-bit, 1 is original 32-bit, > 1 is Modern
- if get_target_info('heapType#') > 1
- throw "known problems with Modern Memory Manager";
- end;
-
- # if the test def is a Maxwell tier 0 app
- case 'MaxT0':
- begin
- # This launchParam is in a variety of test defs... should we remove it???
- end;
-
- default: # {'bitDepth',{}} param, or not a simple string match, or unrecognized
- begin
- throwUp := true;
-
- if typeOf(launchParam) = 'list'
- begin
- if launchparam[1] = 'bitDepth'
- throwUp := false; # just ignore this param here
- end;
-
- if throwUp
- throw "There was an invalid LaunchParam in this test definition- {launchparam}";
- end;
- end; # switch launchParam
- end; # for each launchParam in launchParams
- end; # try
- catch skipReason;
-
- if skipReason
- return {'incomplete', "Skipped '{appName}' - {skipReason}"};
-
- # At this point we are ready to launch the application by the specified method
-
- #SBR 12/20/96 Changed for Radar 1615038
- # Before launching, acquire a lock on the app if necessary
- if SNConflict
- begin
- if not AcquireApplication( appName )
- return {'incomplete', "Skipped '{appName}' - (could not acquire a lock on {appName} from the Arbitrator)"};
- end;
-
- RStatus("LaunchApplication: launching {appName} by {launchBy}", v_level);
-
- theTarget := _Match([target],false,{}); # -1105 is an error here!
-
- if not theTarget
- begin
- RAddResult("LaunchApplication: target crashed before launch");
- return badLaunch;
- end;
-
- if launchBy ~= /agentVU≈/
- begin
- if noCreatorLaunch
- return {'incomplete', "Skipped '{appName}' - noCreatorLaunch"};
-
- if launchBy = 'agentVUFG'
- begin
- appWaitDesc := [application t:appName];
- agentVUMethod := 'into the foreground.';
- end;
- else # launchBy = 'agentVUBG'
- begin
- if not bgLaunchOK
- return {'incomplete', "Skipped '{appName} - it does not support background launch"};
-
- appWaitDesc := [menuItem t:appName m:processMenu];
- agentVUMethod := 'into the background.';
- end;
-
- try
- begin
- tAgentLaunchedAppName := launch(appSig, true, launchBy = 'agentVUFG');
- RAddResult("AgentVU launched '{theActualAppName}' by creator '{appSig}' {agentVUMethod}");
- end;
- catch theError
- begin
- tAgentLaunchedAppName := "";
- switch theError
- begin
- case -1230:
- begin
- RAddResult("AgentVU could not find '{appName}' by creator '{appSig}'");
- launchBy := "Find File ('{launchBy}' could not find it)";
- end;
-
- case -1231:
- begin
- RAddResult("AgentVU could not launch '{appName}', it may need more memory");
- launchBy := "Find File ('{launchBy}' needs more memory)";
- end;
-
- case -1096:
- begin
- RAddResult("Target restarted during Agent VU launch, creator '{appSig}' {agentVUMethod}");
- #do not retry by Finder, fail the test def
- return {'fail', "'{appName}' crashed during Agent VU launch command (-1096)"};
- end;
-
- default:
- begin
- RAddResult("AgentVU returned unknown error {theError} trying to launch '{appName}'");
- launchBy := "Find File ('{launchBy}' failed for unknown reason)";
- end;
- end;
-
- RAddResult("Retrying the launch by Find File");
- end;
- end;
- else if launchBy ~= /VUAid2≈/
- begin
- if launchBy = 'VUAid2FG'
- begin
- appWaitDesc := [application t:appName];
- VUAidMethod := 'into the foreground.';
- end;
- else # launchBy = 'VUAid2BG'
- begin
- if not bgLaunchOK
- return {'incomplete', "Skipped '{appName} - it does not support background launch"};
- appWaitDesc := [menuItem t:appName m:processMenu];
- VUAidMethod := 'into the background.';
- end;
-
- returnVal := VUAid2('launch', appName, {}, launchBy = 'VUAid2FG', true);
- if not returnVal[1]
- RAddResult("VUAid External Tool launched '{appName}' {VUAidMethod} by name");
- else
- begin
- RAddResult("VUAid External Tool could not launch '{appName}' by name");
- return badLaunch;
- end;
- end;
-
-
- if launchBy ~= /Find File≈/
- begin
- if FindFile(appName, 'name', 'is', 0, 'launch', v_level)
- RAddResult("Find File found application {appName} and launched it");
- else
- begin
- RAddResult("Find File did not find '{appName}'.");
-
- # Quit Find File if it is still open.
- if _MatchBoolean([application t:"Find File"])
- begin
- if _MatchBoolean([window t:'' o:1 s:dialog])
- type_keys({returnKey});
- key_eq('q');
- end;
- return badLaunch;
- end;
- appWaitDesc := [application t:appName];
- end;
- else
- begin
- if launchBy ~= /Finder≈/
- begin
- curAppName := _Match([application]).t;
- if curAppName <> 'Finder'
- begin
- if not twitch('Finder')
- begin
- RAddResult("Could not switch to Finder, will try to quit {curAppName}");
- abort_app(-1);
- if not twitch('Finder')
- begin
- RAddResult("Could not quit {curAppName}");
- return badLaunch;
- end;
- end;
- end;
- if appDir # check the expected
- begin
- findResult := find(appName,"appSysFile",,,{appDir});
- appDirString := " inside '{appDir}'";
- end;
- else
- begin
- findResult := find(appName,"appSysFile");
- appDirString := "";
- end;
-
- if not findResult
- begin
- RAddResult("Finder did not find '{appName}'{appDirString}");
- key_eq('w',5);
- return badLaunch;
- end;
-
- key_eq('o',5); # the actual launch with cmd-opt-o (option key) to close window
-
- RAddResult("Finder found '{appName}'{appDirString} and launched it");
-
- finderLaunchWait := 10;
- if not await_absence([application t:'Finder'],finderLaunchWait,,,6)
- begin
- gDialogWindow := false;
- gOtherUnexpectedFlag := true;
- if _MatchBoolean([window o:1 s:dialog])
- CheckLaunchDialog(-1);
- key_eq('w',5);
- RAddResult("Finder was still in the foreground after {finderLaunchWait} seconds");
- return badLaunch;
- end;
- appWaitDesc := [application t:appName];
- end;
- end;
-
- theTarget := _Match([target],false,{}); # -1105 is an error here!
-
- if not theTarget
- begin
- RAddResult("crashed during launch");
- return badLaunch;
- end;
-
- #make sure appWaitDesc appears
- if descType(appWaitDesc) = 'menuItem' # BG launch
- begin
- # first wait for any change in the process menu, then see if it was the right change
- endTime := get_end_time(appWait);
- try while true
- begin
- if timed_out(endTime)
- throw false;
-
- try
- match [menuItem m:processMenu t:$newApList]!; # store current items in process menu
- catch theError
- ExceptionDispatcher(theError,,{"Match 4 in LaunchApplication", {appName, appSig, appDir,
- launchBy, launchParams, appWait, v_level}});
-
- if newApList <> curApList
- throw true;
- end;
- catch appMenuChangedInTime;
-
- if appMenuChangedInTime
- begin
- if select_descriptor(appWaitDesc, 0,6)
- begin
- RAddResult("'{appName}' appeared in the process menu and was selected.");
- end;
- else
- begin
- # the wrong application launched, we have to abort it.
-
- # find which process menu item is the wrong app
- newApListLength := card newApList;
- for thisMenuItem := 1 to newApListLength
- begin
- # use not(a=b) instead of a<>b to handle undefined when last item differs
- # we assume newApList is longer than curApList
-
- if not (newApList[thisMenuItem] = curApList[thisMenuItem])
- begin
- badApName := newApList[thisMenuItem];
- newApListLength := 1;
- end;
- end;
-
- twitch(badApName);
- RAddResult("'{badApName}' unexpectedly appeared in the process menu and was selected.");
- end;
-
- # let the FG transition code do the final reporting
- appWaitDesc := [application t:appName];
- end;
- else
- begin
- RAddResult("'{appName}' did not appear in the process menu after {appWait} seconds.");
- return badLaunch;
- end;
- end;
-
- if descType(appWaitDesc) = 'application' # FG launch, or switch to FG from BG launch
- begin
- endTime := get_end_time(appWait);
- try while true
- begin
- if timed_out(endTime)
- throw false;
-
- newApName := _Match([application]).t;
- if newApName <> curApName
- throw true;
- end;
- catch frontAppChangedInTime;
-
- if frontAppChangedInTime
- begin
- if newApName <> appName
- begin
- # the wrong application launched, we have to abort it.
- badApName := newApName;
- RAddResult("'{badApName}' came to the front instead of '{appName}' - aborting.");
- RAddResult("Please throw away all but one copy of this application or add the");
- RAddResult(" 'noCreatorLaunch' parameter to its test def.");
- abort_app(-1);
- return badLaunch;
- end;
- end;
- else
- begin
- if launchBy ~= /≈BG/
- RAddResult("'{appName}' did not come to the front after selecting it in the Process menu.");
- else
- if ((not gDialogWindow) and gItemFound)
- RAddResult("'{appName}' did not come to the front in {appWait} seconds - it may have crashed");
-
- return badLaunch;
- end;
- end;
-
- RAddResult("'{appName}' came to the front and did not crash");
- return {'pass', launchBy};
- end;
-
-
- #########################################################################
- # task CheckLaunchDialog(v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: If a dialog is displayed at launch time then this task is invoked
- # to analyze such dialog and decide what to do next.
- # Parameters: currentDialog: The current window trait from which the dialog
- # will be analyzed.
- # v_level: verbosity level for log output
- # Returns: internally performs the desired action depending upon the dialog
- # Example: CheckLaunchDialog();
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 10/17/96 Masa Created
- # 10/23/96 Masa added code to improve treatment of unexpected dialogs
- # 10/29/96 Masa fixed matching problem in 'Get static dialog text' code segment
- # 12/10/96 SBR/Masa Changed await_absence(previousDesc to use waitTime instead of default.
- #########################################################################
- task CheckLaunchDialog(v_level := 5)
- begin
- RStatus("Entering CheckLaunchDialog", v_level);
-
- global gDialogWindow;
- global gOtherUnexpectedFlag;
-
- gDialogWindow := true;
- kMaxDialogOrd := 20;
-
- ######## GET STATIC DIALOG TEXT, IF ANY
- ordinality :=2;
- try
- match[window t:'' o:1 s:dialog k:{[staticText o:ordinality t:?dialogStaticText]}];
- catch theError
- ExceptionDispatcher(theError,,{"Match 1 in CheckLaunchDialog", {testType, RunOnlyTheseTests, SkipTheseTests, engineParameters, v_level}});
- While ((not dialogStaticText) and (ordinality < kMaxDialogOrd))
- begin
- ordinality := ordinality +1;
- try
- match[window t:'' o:1 s:dialog k:{[staticText o:ordinality t:?dialogStaticText]}];
- catch theError
- ExceptionDispatcher(theError,,{"Match 2 in CheckLaunchDialog", {testType, RunOnlyTheseTests, SkipTheseTests, engineParameters, v_level}});
- end;
-
- ######## IF TEXT FOUND THEN ANALYZE SOME TYPICAL CASES
- If dialogStaticText
- begin
- #RAddResult('<<< Checking unexpected dialog...');
- if ((dialogStaticText ~= /≈∂n*≈memory≈∂n*≈∂n*/) or (dialogStaticText ~= /≈∂n*≈RAM≈∂n*≈∂n*/)) and
- ((dialogStaticText ~= /≈∂n*≈not≈∂n*≈∂n*/) or (dialogStaticText ~= /≈∂n*≈insufficient≈∂n*≈∂n*/))
- begin
- errDialogText := '';
- for i := 1 to (card dialogStaticText)
- begin
- if dialogStaticText[i] = "∂n" # discard from carriage returns onward
- i := card dialogStaticText;
- else
- errDialogText := errDialogText + dialogStaticText[i];
- end;
- RAddResult("unexpected dialog: {errDialogText}");
- type_keys({returnKey});
- RStatus("unexpected dialog action: pressed the return key", v_level);
- end;
- else
- begin
- if ((dialogStaticText ~= /≈∂n*≈cannot≈∂n*≈∂n*/) or (dialogStaticText ~= /≈∂n*≈Cannot≈∂n*≈∂n*/)) and
- (dialogStaticText ~= /≈∂n*≈start≈∂n*≈∂n*/)
- begin
- errDialogText := '';
- for i := 1 to (card dialogStaticText)
- begin
- if dialogStaticText[i] = "∂n" # discard from carriage returns onward
- i := card dialogStaticText;
- else
- errDialogText := errDialogText + dialogStaticText[i];
- end;
- RAddResult("unexpected dialog: {errDialogText}");
- type_keys({returnKey});
- RStatus("unexpected dialog action: pressed the return key", v_level);
- end;
- else
- begin
- if (dialogStaticText ~= /≈∂n*≈server≈∂n*≈∂n*/)
- begin
- errDialogText := '';
- for i := 1 to (card dialogStaticText)
- begin
- if dialogStaticText[i] = "∂n" # discard from carriage returns onward
- i := card dialogStaticText;
- else
- errDialogText := errDialogText + dialogStaticText[i];
- end;
- RAddResult("unexpected dialog: {errDialogText}");
- type_keys({returnKey});
- RStatus("unexpected dialog action: pressed the return key", v_level);
- end;
- else
- begin
- if (dialogStaticText ~= /≈∂n*≈256≈∂n*≈∂n*/) and
- ((dialogStaticText ~= /≈∂n*≈colors≈∂n*≈∂n*/) or (dialogStaticText ~= /≈∂n*≈color≈∂n*≈∂n*/))
- begin
- errDialogText := '';
- for i := 1 to (card dialogStaticText)
- begin
- if dialogStaticText[i] = "∂n" # discard from carriage returns onward
- i := card dialogStaticText;
- else
- errDialogText := errDialogText + dialogStaticText[i];
- end;
- RAddResult("unexpected dialog: {errDialogText}");
- type_keys({returnKey});
- RStatus("unexpected dialog action: pressed the return key", v_level);
- end;
- else
- begin
- if gOtherUnexpectedFlag
- unexpected_dialog(,,-1);
- end;
- end;
- end;
- end;
- end;
- end;
-
-
- #########################################################################
- # task QuitSequence(appName, theSequence, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Quit an application by a particular method using a custom sequence
- # or the default sequence, unless the target is not capable of it.
- # Parameters: appName: Exact name of the application to quit. The
- # application must already be in the foreground.
- # theSequence: A custom sequence (see AppSequence for details) to quit
- # the application. QuitSequence appends the conditional
- # {[application t:appName],[menuItem t:/Quit≈/ m:2]}
- # to the end of the sequence, and instructs AppSequence
- # not to verify the current app during the conditional.
- # v_level: verbosity level for log output
- # Returns: success: true, failure: false
- # Example: QuitSequence('TeachText 7.0@', );
- # AppSequence('ResEdit™ 2.1.1@', 'RSED', 'ResEdit™ 2.1.1ƒ',,
- # {'noCreatorLaunch'},{[window s:plain],{'key_eq', 'return'},
- # [staticText t:'New File Name:' w:1], {'SFPut', '@!@-ResEdit 1.1.1'},
- # [window t:'@!@-ResEdit 1.1.1']},'Quadra700',,)
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # ??/??/92 SBR Created
- # 02/23/94 SBR Added quitWait value for quit timeout. It was using default 10 seconds.
- # 09/03/94 SBR Added error handling for target access.
- # 04/10/95 SBR Uses ReleaseApplication() to talk to Arbitrator.
- # Formatted source text according to standards.
- # 08/03/95 SBR Changes for Radar 1270966, 1270963
- #########################################################################
- task QuitSequence(appName := '', theSequence := {}, v_level := 4)
- begin
- RStatus("QuitSequence: quitting {appName}", v_level);
- badQuit := {'fail',"'{appName}' did not quit properly"};
-
- if not _MatchBoolean([application t:appName])
- begin
- RAddResult("QuitSequence: '{appName}' was not in the foreground");
- quitSeqPassed := false;
- end;
- else
- begin
- theSequence := # default quit sequence
- theSequence + {{[application t:appName],[menuItem t:/Quit≈/ m:2]}};
- stopAppCheckingAt := card theSequence - 1; # allow custom quit before default
- quitSeqPassed := AppSequence (appName, theSequence, false, stopAppCheckingAt);
- end;
-
- quitWait := 30;
-
- # if not (await_absence([menuItem t:appName],quitWait,,,6) and
- # await_absence([application t:appName],quitWait,,,6))
-
- # new if clause with AwaitAppQuit(), to fix Radar 1270966 and 1270963
- appQuitStatus := AwaitAppQuit(appName, quitWait, -1);
- if isUndefined( appQuitStatus )
- begin
- RAddResult("target crashed while the application was quitting");
- badQuit[2] := badQuit[2] + " - target crashed";
- quitSeqPassed := false;
- end;
- else if not appQuitStatus
- begin
- SysBeep();
- RStatus ("AFTER TRYING TO QUIT, '{appName}' IS STILL ACTIVE. WE'RE TAKING STEPS…", 1);
- abort_app(-1);
- badQuit := {'fail',"'{appName}' did not quit within {quitwait} seconds"};
- quitSeqPassed := false;
- end;
-
- # AFTER THIS POINT, THE APP IS GUARANTEED TO BE NOT RUNNING
-
- if UsingArbitrator()
- begin
- # Un-register the app for SNConflict. If we are using the Arbitrator at all, we send
- # every app name to ReleaseApplication() and let that task decide for us if the
- # application is registered or not. We do this because the actual registration
- # mechanism may change in the future, so keep it in wrapper tasks.
- # If the app was not registered, ReleaseApplication() returns true.
-
- if not ReleaseApplication( appName )
- return {'incomplete', 'QuitSequence: {appName} quit, but ReleaseApplication failed.'};
- end;
-
- # check for crash if sequence passed, Radar 1270963
- if quitSeqPassed
- begin
- theTarget := _Match([target],false,{}); # -1105 is an error here!
-
- if not theTarget
- begin
- badQuit[2] := badQuit[2] + " - target crashed";
- quitSeqPassed := false;
- RAddResult("target crashed after the application quit");
- end;
- else
- begin
- RAddResult("target still running after the application quit");
- end;
- end;
-
- if quitSeqPassed
- begin
- RAddResult("completed quit sequence");
- return {'pass'};
- end;
- else
- begin
- RAddResult("failed quit sequence");
- return badQuit;
- end;
- end;
-
-
- #########################################################################
- # task AppSequence(appName, theSequence, conditional, stopAppCheckingAt, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Execute a list as a sequence of wait/do items
- # Parameters: appName: "": ignore application; used for a quit sequence with
- # conditional save dialog (and future twitch feature)
- # "{string}": this application must remain constant for
- # the entire sequence or the sequence fails.
- # WARNING: twitching applications in a sequence is not yet supported!
- # theSequence: List of things to wait for and do
- # stopAppCheckingAt: Index in theSequence to stop checking the app,
- # mainly during the QuitSequence default conditional.
- # conditional: true if this is a conditional sequence
- # v_level: verbosity level for log output
- # Returns: success: true, failure: false
- # Examples: see AppSequence or QuitSequence;
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 11/07/92 SBR Created as doSequence
- # 10/10/93 SBR Changed to AppSequence
- # 04/10/95 SBR Removed 'restart' selectAction. Added
- # better reporting for move_mouse and type_keys. Moved
- # code for waitItem and doItem into separate tasks. Changed
- # descString from a constructed string to the descriptor
- # as it appears in the sequence. Now reports the ordinal
- # of the sequence item that failed.
- # Formatted source text according to standards.
- # 08/02/95 SBR Changed default v_level from 5 to 4, Radar 1274921
- #########################################################################
- task AppSequence(appName, theSequence, conditional := false, stopAppCheckingAt := 32767, v_level := 4)
- begin
- if conditional
- RAddResult("BEGIN conditional");
-
- waitFor := true;
-
- for sequenceIndex := 1 to card theSequence
- begin
- thing := theSequence[sequenceIndex];
- if conditional
- indexStr := "sub-sequence item {sequenceIndex}";
- else
- indexStr := "sequence item {sequenceIndex}";
-
- if R_BeVerbose(v_level)
- RStatus("AppSequence: {indexStr} is {thing}",v_level);
-
- theTarget := _Match([target],false,{}); # -1105 is an error here!
-
- if not theTarget
- begin
- RAddResult("AppSequence: target crashed at {indexStr}");
- return false;
- end;
-
- if appName and (sequenceIndex < stopAppCheckingAt)
- begin
- if typeOf(thing) = 'string' #Do not do app check if the next
- isNotErrorString := card(thing) <= 1; #item is an error string, we may have
- else
- isNotErrorString := false; #made the app go away on purpose.
-
- if (theTarget.a[1].t <> appName) AND isNotErrorString
- begin
- RAddResult("application disappeared at {indexStr} - it may have crashed");
- return false;
- end;
- end;
-
- if typeOf(thing) = 'descriptor' # convert descriptor to loggable string
- begin
- # thingType := descType(thing);
- #
- # thingName := thing.t;
- # if isUndefined( thingName )
- # thingName := '';
- # else
- # thingName := " t:'{thingName}'";
- #
- # thingOrdinality := '';
- # if thing ~= [contentItem] OR isMember(thingType, { 'menu', 'menuItem', 'window'})
- # begin
- # thingOrdinality := thing.o;
- # if isUndefined( thingOrdinality )
- # thingOrdinality := '';
- # else
- # thingOrdinality := " o:'{thingOrdinality}'";
- # end;
- #
- # windowStyle := '';
- # if thingType = 'window'
- # begin
- # switch thing.s
- # begin
- # case dialog:
- # windowStyle := ' s:dialog';
- # case document:
- # windowStyle := ' s:document';
- # case da:
- # windowStyle := ' s:da';
- # case plain:
- # windowStyle := ' s:plain';
- # case shadow:
- # windowStyle := ' s:shadow';
- # end;
- # end;
- # descString := "[{thingType}{thingName}{thingOrdinality}{windowStyle}]";
- descString := "{thing}";
- end;
-
- ### WAIT ITEM
- if waitFor
- begin
- try
- begin
- previousThing := thing; # if we want to select it later
- LQWaitItem( { appName, thing, conditional, sequenceIndex, stopAppCheckingAt }, v_level );
- end;
- catch theWaitInterruption
- begin
- return theWaitInterruption;
- end;
- end;
-
- ### DO ITEM
- else begin
- try
- begin
- LQDoItem( { thing, previousThing }, v_level );
- end;
- catch theDoInterruption
- begin
- return theDoInterruption;
- end;
- end;
-
- waitFor := not waitFor;
- end; # for each thing in theSequence
-
- if conditional
- RAddResult("END conditional (passed)");
- return true;
- end;
-
-
- #########################################################################
- # task LQWaitItem(waitInfoList, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Waits for an item to appear or does something else passively.
- # Parameters: waitInfoList: list containing info for waiting
- # { appName, thing, conditional, sequenceIndex, stopAppCheckingAt }
- # v_level: verbosity level for reporting
- # Returns: nothing (throws true or false to support sub-sequence recursion)
- # Example: try LQWaitItem({appName,thing,conditional,sequenceIndex,stopAppCheckingAt});
- # catch theWaitInterruption
- # return theWaitInterruption
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 02/25/95 SBR created by moving code from appSequence()
- # 07/30/95 SBR Use GetLQWaitItemTimeout() for Radar 1274920
- # Fix for Radar 1272949.
- #########################################################################
- task LQWaitItem( waitInfoList, v_level := 4)
- begin
- appName := waitInfoList[1];
- thing := waitInfoList[2];
- conditional := waitInfoList[3];
- sequenceIndex := waitInfoList[4];
- stopAppCheckingAt := waitInfoList[5];
-
- switch typeOf(thing)
- begin
- case 'descriptor':
- begin
- # fix for Radar 1274920
- waitTime := GetLQWaitItemTimeout( thing, conditional, v_level);
- # if conditional
- # begin
- # if (descType(thing) = 'application') # adjust time for type of awaitItem
- # waitTime := 2;
- # else
- # waitTime := 10;
- # end;
- # else
- # waitTime := 150;
-
- if await_presence(thing,waitTime,,,6)
- RAddResult("{thing} present");
- else
- begin
- RAddResult("{thing} not present after {waitTime} seconds");
- if conditional
- begin
- #if thing = theSequence[1]
- if sequenceIndex = 1
- begin
- ##SBR Debug stuff
- # global gWastedTime := gWastedTime + waitTime;
- # println " ••Conditional Timeout - wasted {waitTime} seconds! (total {gWastedTime})••";
-
- throw RAddResult("END conditional (ignored)");
- end;
- else
- throw not RAddResult("END conditional (failed)");
- end;
- else
- throw false;
- end;
- end;
-
- case 'integer':
- begin
- wait(thing);
- RAddResult("waited {thing} seconds");
- end;
-
- case 'list':
- begin
- if sequenceIndex < stopAppCheckingAt
- begin
- # to fix Radar 1272949; special conditional waits until app quits
- # we have to stop checking for the app when it quits!
- if thing = {[application t:appName],'>'}
- subSequenceStopAppCheckAt := 0;
- else
- subSequenceStopAppCheckAt := 32767;
- end;
- else
- subSequenceStopAppCheckAt := 0;
-
- if not AppSequence(appName, thing, true, subSequenceStopAppCheckAt)
- throw false;
- end;
-
- case 'string': # empty string means don't wait for anything
- begin
- if thing # non-empty string means log it as a failure report
- throw not RAddResult("sequence failed because: {thing}");
- end;
- end;
- end;
-
-
- #########################################################################
- # task GetLQWaitItemTimeout( waitDesc, conditional, v_level )
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Determines the time to wait for a descriptor.
- # If gDevelopmentMode is true, the non-conditional timeout is short.
- # Parameters: waitDesc: the descriptor to wait for
- # conditional: Boolean true: this a conditional wait item
- # false: this a normal wait item
- # v_level: verbosity level for reporting
- # Returns: number of seconds to wait for the item
- # Example: GetLQWaitItemTimeout
- # Assumptions: VU 2.1, gDevelopmentMode = true if using Dev Launchquits
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 07/30/95 SBR created to fix for Radar 1274920
- #########################################################################
- task GetLQWaitItemTimeout( waitDesc, conditional, v_level := 4)
- begin
- global gDevelopmentMode;
-
- if conditional
- begin
- if (descType(waitDesc) = 'application') # adjust time for type of awaitItem
- waitTime := 2;
- else
- waitTime := 10;
- end;
- else
- begin
- if gDevelopmentMode
- waitTime := 10;
- else
- waitTime := 150;
- end;
- return waitTime;
- end;
-
-
- #########################################################################
- # task LQDoItem(doInfoList, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Selects or does some other action.
- # Parameters: doInfoList: list containing info for doing something
- # { thing, previousDesc }
- # v_level: verbosity level for reporting
- # Returns: nothing (throws true or false to support sub-sequence recursion)
- # Example: try LQDoItem({appName,thing,conditional,sequenceIndex,stopAppCheckingAt});
- # catch theDoInterruption
- # return theDoInterruption
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 02/25/95 SBR created by moving code from appSequence
- # 02/25/95 SBR removed support for restarting in the sequence
- #########################################################################
- task LQDoItem(doInfoList, v_level := 4)
- begin
- thing := doInfoList[1];
- previousDesc := doInfoList[2];
-
- switch typeOf(thing)
- begin
- case 'descriptor':
- begin
- temp := select_descriptor(thing,,5);
- if temp
- RAddResult("{thing} selected");
- else
- throw not RAddResult("{thing} not selected");
- end;
-
- case 'string':
- begin
- switch thing
- begin
- case '':; # empty string means don't do anything
-
- case '<': # select the desc we just waited for
- begin
- if select_descriptor(previousDesc, 0)
- RAddResult("{previousDesc} selected");
- else
- throw not RAddResult("{previousDesc} not selected");
- end;
-
- case '>': # awaitAbsence the desc we just waited for
- begin
- waitTime := GetLQWaitItemTimeout( previousDesc, false, v_level);
- if await_absence(previousDesc,waitTime,,,6)
- RAddResult("{previousDesc} absent");
- else
- throw not RAddResult("{previousDesc} not absent");
- end;
-
- default: # log the string as a failure report
- begin
- throw not RAddResult("sequence failed because: {thing}");
- end;
- end;
- end;
-
- case 'integer':
- begin
- wait(thing);
- RAddResult("waited {thing} seconds");
- end;
-
- case 'list': # flexible selection operator
- begin
- selectAction := thing[1];
-
- switch selectAction
- begin
- case 'type_keys': # type something
- begin
- tkList := thing[2];
- oldSpeed := typeSpeed(50);
- type_keys(tkList);
- typeSpeed(oldSpeed);
- RAddResult("type_keys: {tkList}");
- end;
-
- case 'fieldSequence': # enter data in tab-seperated fields
- begin
- fsList := thing[2];
- for each fieldEntry in fsList begin
- oldSpeed := typeSpeed(50);
- type_keys({fieldEntry, tabKey});
- RAddResult("typed '{fieldEntry}' into a field, then auto-tabKey");
- typeSpeed(oldSpeed);
- end;
- end;
-
- case 'key_eq': # do a command-key equivalent
- begin
- typeChars := thing[2];
- key_eq(typeChars);
- RAddResult("typed '{typeChars}' with command key down");
- end;
-
- case 'SFGet': # do a generic SFGet dialog
- begin
- typeChars := thing[2];
- type_keys({typeChars, returnKey});
- RAddResult("typed '{typeChars}' then returnKey in SFGet");
- end;
-
- case 'SFPut': # do a generic SFPutFile,
- begin # replace if necessary
- typeChars := thing[2];
- type_keys({typeChars, returnKey});
- RAddResult("typed '{typeChars}' then returnKey in SFPut");
- if select_descriptor([button t:'Replace'], 2, 6)
- RAddResult("'{typeChars}' already existed, selected [button t:'Replace']");
- end;
-
- case 'SFPutNewName': # do a generic SFPutFile,
- begin # do not replace, make a new name
- typeChars := thing[2];
- type_keys({typeChars, returnKey});
- RAddResult("typed '{typeChars}' then returnKey in SFPutNewName");
- newFileName := typeChars;
- while await_presence([button t:'Replace' w:1],2,,,6)
- begin
- RAddResult("'{newFileName}' already existed");
- select_descriptor([button t:'Cancel' w:1],2,6);
- randNew := random();
- newFileName := "{typeChars} {randNew}";
- type_keys({newFileName, returnKey});
- RAddResult("typed '{newFileName}' then returnKey in SFPutNewName");
- end;
- end;
-
- case 'move_mouse':
- begin
- mmList := thing[2];
- move_mouse(mmList);
- RAddResult("move_mouse: {mmList}");
- end;
-
- default:
- begin
- throw not RAddResult("'{selectAction}' is not a known thing to do");
- end;
- end; # switch selectAction
- end; # case 'list'
- end; # switch typeOf(thing)
- end;
-
-
- #########################################################################
- # task Quit_Apps(appNames, appNamesAreExceptions, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Quits the specified applications in the fastest possible manner.
- # (To quit only the front application, use the abort_app() task).
- # Parameters: appNames: list of exact application names
- # appNamesAreExceptions:
- # true: quit all except Finder and apps in the list
- # false: quit all apps in appNames
- # v_level: verbosity level for log output
- # Returns: nothing (will not return until successful)
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 02/12/93 SBR Created
- # 08/02/95 SBR Changes to fix Radar 1270966
- #########################################################################
- task Quit_Apps(appNames := {}, appNamesAreExceptions := false, v_level := 4)
- begin
- global gDialogWindow;
- global gOtherUnexpectedFlag;
-
- if appNamesAreExceptions
- begin
- done := false;
- showedAll := false;
-
- while not done
- begin
- currentApp:= _Match ([application]).t;
-
- RStatus("Quit_Apps: Current app is '{currentApp}'.", v_level);
-
- if currentApp <> 'Finder'
- begin
- if not isMember(currentApp, appNames)
- abort_app();
- else
- begin
- gDialogWindow := false;
- gOtherUnexpectedFlag := true;
- if _MatchBoolean([window o:1 s:dialog])
- CheckLaunchDialog(-1);
-
- if not twitch(Finder)
- RStatus ("Quit_Apps: Can not switch to the Finder from {currentApp}.", 1);
-
- myWaitVal:= GetLQWaitItemTimeout([application t:currentApp], false);
- await_absence([application t:currentApp], myWaitVal);
- end;
- end;
- else
- begin #we are in the Finder
- gDialogWindow := false;
- gOtherUnexpectedFlag :=true;
- if _MatchBoolean([window o:1 s:dialog])
- CheckLaunchDialog(-1);
-
- try
- match[menuItem o:1 t:'Hide Finder' m:[menu o:?processMenu]];
- catch theError
- ExceptionDispatcher(theError,,{"Match 1 in Quit_Apps", {appNames, appNamesAreExceptions, v_level}});
-
- if not showedAll
- begin
- if _MatchBoolean([menuItem t:'Show All' m:processMenu e:true], true) ## do an exact match
- _SelectBoolean([menuItem t:'Show All' m:processMenu e:true], true); ## do an exact select
- showedAll := true;
- end;
-
- # Here, o:6 m:processMenu would indicate that something other than the finder
- # is in the process menu. This part of the script could break if process menu
- # ordinalities change
-
- if _MatchBoolean([menuItem o:6 m:processMenu])
- begin
- select_descriptor([menuItem t:'Hide Finder' m:processMenu]);
- await_absence([application t:'Finder']);
- abort_app();
- end;
- else
- done := true;
- end;
- end;
- end;
- else while appNames
- begin
- gDialogWindow := false;
- gOtherUnexpectedFlag := true;
- if _MatchBoolean([window o:1 s:dialog])
- CheckLaunchDialog(-1);
-
- currentApp := _Match ([application]).t;
-
- appIndex := isMember(currentApp,appNames);
- if appIndex
- begin
- abort_app();
- appNames := remove(appIndex, appNames);
- end;
- else
- begin
- appToQuit := appNames[1];
- # begin new code for Radar 1270966
- try
- match [menu o:$menuOrds];
- catch theError
- ExceptionDispatcher(theError,,{"Match 2 in Quit_Apps", {appNames, appNamesAreExceptions, v_level}});
-
- processMenu := menuOrds[card menuOrds];
- # end new code for Radar 1270966
-
- if select_menuItem(appToQuit,processMenu)
- begin
- if await_presence([application t:appToQuit],,,,6)
- abort_app();
- else
- RIncomplete("Quit_Apps: {appToQuit} did not appear in front after app menu selection.", v_level);
- end;
- else
- RIncomplete("Quit_Apps: {appToQuit} is not in front or in the application menu.", v_level);
- appNames := remove(1, appNames);
- end;
- end;
- end;
-
-
- #########################################################################
- # task AwaitAppQuit( pAppName, pTimeout, v_level )
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Ensures an application has quit within the specified timeout.
- # Does NOT take any action to quit, merely verifies it is not
- # in the foreground or background.
- # Parameters: pAppName: string name of the application
- # pTimeLimit: seconds to wait before failing
- # v_level: verbosity level for reporting
- # Returns: true: application quit within pTimeLimit seconds
- # false: application did not quit within pTimeLimit seconds
- # undefined: target crashed or other unexpected ScriptError()
- # Example: appName := "SimpleText";
- # if not AwaitAppQuit( appName )
- # RError("Application {appName} did not quit");
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 08/02/95 SBR created to fix Radar 1270966
- #########################################################################
- task AwaitAppQuit( pAppName, pTimeLimit := 10, v_level := 4)
- begin
- wait_end := get_end_time(pTimeLimit); # Reset the time limit timer
-
- try while true
- begin
- appInForeground := _matchBoolean([application t:pAppName], true);
-
- # check for error, e.g. crash
- if isUndefined(appInForeground)
- throw undefined;
-
- if not appInForeground
- begin
- try
- match [menu o:$menuOrds];
- catch theError
- begin
- ExceptionDispatcher(theError,,{"Match 1 in AwaitAppQuit", {pAppName, pTimeLimit, v_level}});
- throw undefined;
- end;
-
- processMenu := menuOrds[card menuOrds];
- appInBackground := _matchBoolean([menuItem t:pAppName m:processMenu], true);
-
- # check for error, e.g. crash
- if isUndefined(appInBackground)
- throw undefined;
-
- if not appInBackground
- throw true;
- end;
-
- if timed_out(wait_end)
- begin
- RIncomplete("AwaitAppQuit: {pAppName} did not quit in {pTimeLimit} seconds",v_level);
- throw false;
- end;
- end;
- catch theResult;
-
- return theResult;
- end;
-
-
- #########################################################################
- # task AcquireApplication(appName, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Uses the Arbitrator to reserve an application for exclusive use.
- # See the Arbitrator Script for more explanations.
- # Parameters: appName: The exact string name of the application test def.
- # v_level: verbosity level for reporting
- # Returns: true if successful, false if not
- # Examples: RegisterApplication('4th Dimension 2.2.3@')
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 01/14/94 SBR Created as RegisterApplication
- # 09/29/94 SBR Changed to use Arbitrator external tool
- # 02/20/95 SBR Changed to AcquireApplication, uses AcquireID()
- #########################################################################
- task AcquireApplication(appName, v_level := 2)
- begin
- global gAcquiredApps;
- acquireWaitTime := 60;
- totalWaitTime := 0;
-
- if isUndefined(gAcquiredApps)
- gAcquiredApps := {};
-
- appIsRegistered := false;
-
- while not appIsRegistered #loop here until app becomes available
- begin
- appIsRegistered := AcquireID( {'application', appName} );
-
- if not appIsRegistered
- begin
- if totalWaitTime = 0
- RStatus("Waiting to use {appName} because it is in use somewhere else.",v_level);
- wait(acquireWaitTime);
- totalWaitTime := totalWaitTime + acquireWaitTime;
- end;
- else begin
- gAcquiredApps := gAcquiredApps + {appName};
- if totalWaitTime <> 0
- RStatus("After {totalWaitTime} seconds, {appName} became available.",v_level);
- end;
- end;
- return true;
- end;
-
-
- #########################################################################
- # task ReleaseApplication(appName, v_level)
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # Description: Uses the Arbitrator to make an application available for other scripts.
- # See the Arbitrator Script for more explanations.
- # Parameters: appName: The exact string name of the application test def.
- # v_level: verbosity level for reporting
- # Returns: true if successful, false if not
- # Examples: ReleaseApplication('4th Dimension 2.2.3@')
- # Assumptions: VU 2.1
- #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- # History:
- # 01/14/94 SBR Created as UnRegisterApplication
- # 09/29/94 SBR Changed to use Arbitrator external tool
- # 02/20/95 SBR Changed to ReleaseApplication, uses ReleaseID()
- #########################################################################
- task ReleaseApplication(appName, v_level := 5)
- begin
- global gAcquiredApps;
-
- if isUndefined(gAcquiredApps)
- gAcquiredApps := {};
-
- appIsRegistered := isMember(appName, gAcquiredApps);
- if appIsRegistered # we have acquired this app
- begin
- releaseStatus := ReleaseID( {'application',appName} );
-
- if releaseStatus
- begin
- gAcquiredApps := remove(appIsRegistered, gAcquiredApps);
- return true;
- end;
- else begin
- RIncomplete("ReleaseApplication: Arbitrator failed to release: {arbResponse}.",v_level);
- return false;
- end;
- end;
- else begin
- return true; # if it was never acquired, it is released!
- end;
- end;
-
-
-